package com.scau402.system1.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.scau402.common.utils.PageUtils;
import com.scau402.system1.domain.bo.WmsInboundOrderBO;
import com.scau402.system1.domain.factory.WmsInboundOrderFactory;
import com.scau402.system1.domain.po.WmsAuditOrderPO;
import com.scau402.system1.domain.po.WmsInboundOrderDetailPO;
import com.scau402.system1.domain.po.WmsInboundOrderPO;
import com.scau402.system1.domain.query.WmsInboundOrderQuery;
import com.scau402.system1.domain.vo.*;
import com.scau402.system1.mapper.IWmsInboundOrderDetailMapper;
import com.scau402.system1.mapper.IWmsInboundOrderMapper;
import com.scau402.system1.repository.IWmsInboundOrderRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import javax.swing.text.html.Option;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 
 * @create 2024/1/2 18:38
 * @description
 */
@Repository
@Slf4j
public class WmsInboundOrderRepositoryImpl implements IWmsInboundOrderRepository {

    @Autowired
    private IWmsInboundOrderMapper wmsInboundOrderMapper;

    @Autowired
    private IWmsInboundOrderDetailMapper wmsInboundOrderDetailMapper;

    @Autowired
    private WmsInboundOrderFactory wmsInboundOrderFactory;

    @Override
    public List<WmsInboundOrderBO> getByCondition(WmsInboundOrderQuery wmsInboundOrderQuery) {
        log.info("wmsInboundOrderQuery：{}", wmsInboundOrderQuery);

        // 根据查询条件查询入库单PO列表
        WmsInboundOrderPO wmsInboundOrderPO = wmsInboundOrderFactory.toWmsInboundOrderPO(wmsInboundOrderQuery);
        if (Objects.isNull(wmsInboundOrderPO)) {
            log.error("入库单查询条件为空，入库单查询条件：{}", wmsInboundOrderQuery);
            return new ArrayList<>();
        }
        // 默认查询未删除的入库单
        wmsInboundOrderPO.setDelFlag("0");
        LambdaQueryWrapper<WmsInboundOrderPO> lambdaQueryWrapper = Wrappers.lambdaQuery(wmsInboundOrderPO)
                .orderByDesc(WmsInboundOrderPO::getCreateTime);
        // 分页
        PageUtils.startPage();
        List<WmsInboundOrderPO> wmsInboundOrderPOList = wmsInboundOrderMapper.selectList(lambdaQueryWrapper);
        // wmsInboundOrderPOList是Page类型携带分页信息的，需要将分页信息设置到MDC中
        PageInfo<WmsInboundOrderPO> pageInfO1 = new PageInfo<>(wmsInboundOrderPOList);
        PageUtils.fetchSessionPageInfo(pageInfO1);
        log.info("wmsInboundOrderPOList size：{}", wmsInboundOrderPOList.size());
        log.info("wmsInboundOrderPOList：{}", wmsInboundOrderPOList);
        if (CollectionUtils.isEmpty(wmsInboundOrderPOList)) {
            log.warn("入库单为空，wmsInboundOrderQuery：{}", wmsInboundOrderQuery);
            return new ArrayList<>();
        }

        List<String> inboundOrderCodeList = wmsInboundOrderPOList.stream()
                .map(WmsInboundOrderPO::getOrderCode)
                .collect(Collectors.toList());

        // 根据入库单PO的入库单编号查询入库单明细PO列表，构造map<入库单编号，入库单明细PO列表>
        Map<String, List<WmsInboundOrderDetailPO>> inboundOrderDetailMap = CollectionUtils.isEmpty(inboundOrderCodeList)
                ? new HashMap<>(0)
                : getWmsInboundOrderDetailPOList(inboundOrderCodeList)
                .stream()
                .collect(Collectors.groupingBy(WmsInboundOrderDetailPO::getInboundOrderCode));
        // 收集value为空的key列表
        List<String> emptyKeyList = new ArrayList<>();
        if (CollectionUtils.isEmpty(inboundOrderDetailMap)) {
            emptyKeyList.addAll(inboundOrderCodeList);
        } else {
            inboundOrderDetailMap.forEach((key, value) -> {
                if (CollectionUtils.isEmpty(value)) {
                    emptyKeyList.add(key);
                }
            });
        }
        if (emptyKeyList.size() > 0) {
            log.error("以下入库单的入库单明细为空，入库单编号：{}", emptyKeyList);
        }

        // 根据入库单PO列表和入库单明细PO列表构造入库单BO列表
        List<WmsInboundOrderBO> wmsInboundOrderBOList = wmsInboundOrderFactory.toWmsInboundOrderBOList(wmsInboundOrderPOList, inboundOrderDetailMap);
        log.info("wmsInboundOrderBOList: {}", wmsInboundOrderBOList);

        return wmsInboundOrderBOList;
    }

    @Override
    public List<WmsInboundOrderBO> findByOrderCodeList(List<String> inboundOrderIdList, Long tenantId, boolean page) {
        log.info("inboundOrderIdList：{}", inboundOrderIdList);
        log.info("tenantId：{}", tenantId);

        // 根据入库单编号列表查询入库单PO列表
        if (page) {
            PageUtils.startPage();
        }
        List<WmsInboundOrderPO> wmsInboundOrderPOList = Optional
                .ofNullable(wmsInboundOrderMapper.selectList(Wrappers.<WmsInboundOrderPO>lambdaQuery()
                        .eq(WmsInboundOrderPO::getDelFlag, '0')
                        .eq(WmsInboundOrderPO::getTenantId, tenantId)
                        .in(WmsInboundOrderPO::getOrderCode, inboundOrderIdList)))
                .orElse(new ArrayList<>(0));
        if (CollectionUtils.isEmpty(wmsInboundOrderPOList)) {
            log.warn("入库单id为空，inboundOrderIdList：{}", inboundOrderIdList);
            return new ArrayList<>();
        }
        // wmsInboundOrderPOList是Page类型携带分页信息的，需要将分页信息设置到MDC中
        if (page) {
            PageInfo<WmsInboundOrderPO> pageInfO1 = new PageInfo<>(wmsInboundOrderPOList);
            PageUtils.fetchSessionPageInfo(pageInfO1);
        }
        log.info("wmsInboundOrderPOList size：{}", wmsInboundOrderPOList.size());
        log.info("wmsInboundOrderPOList：{}", wmsInboundOrderPOList);

        List<String> inboundOrderCodeList = wmsInboundOrderPOList.stream().map(WmsInboundOrderPO::getOrderCode).collect(Collectors.toList());

        // 根据入库单PO的入库单编号查询入库单明细PO列表，构造map<入库单编号，入库单明细PO列表>
        Map<String, List<WmsInboundOrderDetailPO>> inboundOrderDetailMap = CollectionUtils.isEmpty(inboundOrderCodeList)
                ? new HashMap<>(0)
                : getWmsInboundOrderDetailPOList(inboundOrderCodeList)
                .stream()
                .collect(Collectors.groupingBy(WmsInboundOrderDetailPO::getInboundOrderCode));
        // 收集value为空的key列表
        List<String> emptyKeyList = new ArrayList<>();
        if (CollectionUtils.isEmpty(inboundOrderDetailMap)) {
            emptyKeyList.addAll(inboundOrderCodeList);
        } else {
            inboundOrderDetailMap.forEach((key, value) -> {
                if (CollectionUtils.isEmpty(value)) {
                    emptyKeyList.add(key);
                }
            });
        }
        if (emptyKeyList.size() > 0) {
            log.error("以下入库单的入库单明细为空，入库单编号：{}", emptyKeyList);
        }

        // 根据入库单PO列表和入库单明细PO列表构造入库单BO列表
        List<WmsInboundOrderBO> wmsInboundOrderBOList = wmsInboundOrderFactory.toWmsInboundOrderBOList(wmsInboundOrderPOList, inboundOrderDetailMap);
        log.info("wmsInboundOrderBOList: {}", wmsInboundOrderBOList);

        return wmsInboundOrderBOList;
    }

    /**
     * 根据入库单号列表获取入库单VO列表
     * @param orderCodes 入库单号列表
     * @return VO列表
     */
    @Override
    public List<WmsInboundOrderExportVO> findListByOrderCodes(List<String> orderCodes) {
        if (orderCodes.isEmpty()) {
            return new ArrayList<>();
        }
        List<WmsInboundOrderExportVO> voList = wmsInboundOrderMapper.selectInboundOrderVOByOrderCodes(orderCodes);
        log.info("inbound export voList: {}",voList.size());
        return voList;
    }

    /**
     * 根据入库单号列表获取入库单详情VO列表
     * @param orderCodes 入库单号列表
     * @return VO列表
     */
    @Override
    public List<WmsInboundOrderDetailExportVO> findDetailListByOrderCodes(List<String> orderCodes) {
        if (orderCodes.isEmpty()) {
            return new ArrayList<>();
        }
        List<WmsInboundOrderDetailExportVO> voList = wmsInboundOrderDetailMapper.selectInboundDetailVOByOrderCodes(orderCodes);
        log.info("inbound export voList : " +voList.size());
        return voList;
    }

    /**
     * 根据审核单信息获取关联的入库单和详情单VO
     * @param po 审核单信息
     * @return VO
     */
    @Override
    public WmsInboundOrderAndDetailVO findInboundAndDetailByAudit(WmsAuditOrderPO po) {
        if (po == null||po.getId()==null) {
            return null;
        }
        WmsInboundOrderVO inboundVO = wmsInboundOrderMapper.selectVOByAuditId(po.getId());
        List<WmsInboundOrderDetailVO> detailVOList = wmsInboundOrderDetailMapper.selectInboundDetailVOByOrderCode(inboundVO.getOrderCode());
        return new WmsInboundOrderAndDetailVO(inboundVO,detailVOList);
    }

    /**
     * 根据审核单获取关联的入库单PO
     * @param audit 审核单信息
     * @return 入库单PO
     */
    @Override
    public WmsInboundOrderPO findInboundByAudit(WmsAuditOrderPO audit) {
        return wmsInboundOrderMapper.selectOne(new QueryWrapper<WmsInboundOrderPO>().eq("audit_id",audit.getId()));
    }

    /**
     * 根据入库单号获取详情单列表
     * @param orderCode 入库单号
     * @return 详情单列表
     */
    @Override
    public List<WmsInboundOrderDetailPO> findInboundDetailByOrderCode(String orderCode) {
        return wmsInboundOrderDetailMapper.selectList(new QueryWrapper<WmsInboundOrderDetailPO>().in("inbound_order_code",orderCode));
    }

    /**
     * 通过入库单号列表获取入库单详情PO列表
     * @param inboundOrderCodeList 入库单号列表
     * @return 入库单详情PO列表
     */
    private List<WmsInboundOrderDetailPO> getWmsInboundOrderDetailPOList(List<String> inboundOrderCodeList) {
        return Optional
                .ofNullable(wmsInboundOrderDetailMapper.selectList(Wrappers.<WmsInboundOrderDetailPO>lambdaQuery()
                        .eq(WmsInboundOrderDetailPO::getDelFlag, '0')
                        .in(WmsInboundOrderDetailPO::getInboundOrderCode, inboundOrderCodeList)))
                .orElse(new ArrayList<>(0));
    }
}
